Flags from custom build script are now used
authorPierre Krieger <pierre.krieger1708@gmail.com>
Mon, 27 Oct 2014 15:29:03 +0000 (16:29 +0100)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 5 Nov 2014 19:37:34 +0000 (11:37 -0800)
src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_compile_custom_build.rs

index 84a6979c849602522c3edb704164b78759fcac8b..842654207f6d8b8f67032074f349f503cb896d21 100644 (file)
@@ -1,7 +1,8 @@
 use std::collections::HashSet;
 use std::dynamic_lib::DynamicLibrary;
-use std::io::{fs, BufReader, USER_RWX};
-use std::io::fs::PathExtensions;
+use std::io::{fs, BufferedReader, BufReader, USER_RWX};
+use std::io::fs::{File, PathExtensions};
+use std::os;
 
 use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
 use util::{mod, CargoResult, ProcessBuilder, CargoError, human, caused_human};
@@ -512,12 +513,60 @@ fn rustc(package: &Package, target: &Target,
         let show_warnings = package.get_package_id() == cx.resolve.root() ||
                             is_path_source;
         let rustc = if show_warnings {rustc} else {rustc.arg("-Awarnings")};
+        let build_cmd_layout = cx.layout(package, KindForHost);
+
+        // building the possible `build/$pkg/output` file for this local package
+        let command_output_file = build_cmd_layout.build(package).join("output");
+
+        // building the list of all possible `build/$pkg/output` files
+        // whether they exist or not will be checked during the work
+        let command_output_files = cx.dep_targets(package).iter().map(|&(pkg, _)| {
+            build_cmd_layout.build(pkg).join("output")
+        }).collect::<Vec<_>>();
 
         (proc() {
+            let mut rustc = rustc;
+
+            let mut additional_library_paths = Vec::new();
+
+            // list of `-l` flags to pass to rustc coming from custom build scripts
+            let additional_library_links = match File::open(&command_output_file) {
+                Ok(f) => {
+                    let flags = try!(CustomBuildCommandOutput::parse(
+                        BufferedReader::new(f), name.as_slice()));
+
+                    additional_library_paths.extend(flags.library_paths.iter().map(|p| p.clone()));
+                    flags.library_links.clone()
+                },
+                Err(_) => Vec::new()
+            };
+
+            // loading each possible custom build output file to fill `additional_library_paths`
+            for flags_file in command_output_files.into_iter() {
+                let flags = match File::open(&flags_file) {
+                    Ok(f) => f,
+                    Err(_) => continue  // the file doesn't exist, probably means that this pkg
+                                        // doesn't have a build command
+                };
+
+                let flags = try!(CustomBuildCommandOutput::parse(
+                    BufferedReader::new(flags), name.as_slice()));
+                additional_library_paths.extend(flags.library_paths.iter().map(|p| p.clone()));
+            }
+
+            for p in additional_library_paths.into_iter() {
+                rustc = rustc.arg("-L").arg(p);
+            }
+            for lib in additional_library_links.into_iter() {
+                rustc = rustc.arg("-l").arg(lib);
+            }
+
             try!(rustc.exec().chain_error(|| {
                 human(format!("Could not compile `{}`.", name))
             }));
+
             Ok(())
+
         }, kind, desc)
     }).collect())
 }
index 97bcfd6dea37325a572aa11b257330d642fa77d4..99ba07c2d913e01e846bb82ef7997091e9d4d025 100644 (file)
@@ -1,4 +1,7 @@
+use std::path;
+
 use support::{project, execs};
+use support::{COMPILING, RUNNING};
 use hamcrest::{assert_that};
 
 fn setup() {
@@ -151,3 +154,55 @@ Only `-l` and `-L` flags are allowed in build script of `foo v0.5.0 (file://{})`
 `",
 p.root().display())));
 })
+
+/*
+test!(custom_build_script_rustc_flags {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+
+            name = "bar"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [dependencies.foo]
+            path = "foo"
+        "#)
+        .file("src/main.rs", r#"
+            fn main() {}
+        "#)
+        .file("foo/Cargo.toml", r#"
+            [project]
+
+            name = "foo"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+            build = "build.rs"
+        "#)
+        .file("foo/src/lib.rs", r#"
+        "#)
+        .file("foo/build.rs", r#"
+            fn main() {
+                println!("cargo:rustc-flags=-l nonexistinglib -L /dummy/path1 -L /dummy/path2");
+            }
+        "#);
+
+    // TODO: TEST FAILS BECAUSE OF WRONG STDOUT (but otherwise, the build works)
+    assert_that(p.cargo_process("build").arg("--verbose"),
+                execs().with_status(101)
+                       .with_stdout(format!("\
+{compiling} bar v0.5.0 ({url})
+{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib -g \
+        -C metadata=[..] \
+        -C extra-filename=-[..] \
+        --out-dir {dir}{sep}target \
+        --dep-info [..] \
+        -L {dir}{sep}target \
+        -L {dir}{sep}target{sep}deps`
+",
+running = RUNNING, compiling = COMPILING, sep = path::SEP,
+dir = p.root().display(),
+url = p.url(),
+)));
+})
+*/